;;; buildxml-mode.el --- mode for google's build.xml

;; Copyright (C) 2011 zxy
;; Author: zxy <gcoordinate@gmail.com>
;; Maintainer: zxy <gcoordinate@gmail.com>
;; Created: Dec 2011
;; Version: 1.3.1

;;
;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 3 of the License, or
;; (at your option) any later version.
;;
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with this program; see the file COPYING.  If not, write to
;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.

;; Installation instructions
;; --------------------------------
;; (setq gae-java-root-path (concat program-path"appengine-java-sdk-1.6.2.1/"))
;; (add-to-list 'load-path (concat plugin-path "appengine-emacs-toolkit"))
;; (require 'buildxml-mode)
;; (add-hook 'buildxml-mode-hook
;;           (lambda ()
;;             (progn (local-set-key "\C-ca" 'gae-java-ant-build)
;;                    (local-set-key "\C-cc" 'gae-java-start-appserver)
;;                    (local-set-key "\C-cb" 'appengine-browse-appserver)
;;                    (local-set-key "\C-cu" 'gae-java-update-appserver))))

(load-file (replace-regexp-in-string "buildxml-mode.el" "appengine-common.el" load-file-name))
(message (concat "Loading " load-file-name))

;; public var

(defvar gae-java-root-path nil
  "*path of gae")

(defvar gae-java-template-directory
  (concat gae-java-root-path"/demos/new_project_template")
  "*Project template for java")

;; public defun

(defun gae-java-ant-build ()
  "Build with ant"
  (interactive)
  (unless (and (not (equal nil gae-java-root-path))
               (file-exists-p gae-java-root-path))
    (error "[appengine] Cannot find gae-java-root-path."))
  (save-some-buffers)
  (setq proname (replace-regexp-in-string "build.xml" "" buffer-file-name))
  (shell "*appengine-temp*")
  (comint-send-string (current-buffer) (concat "echo '[appengine] AppServer build "proname"...' \n"))
  (comint-send-string (current-buffer) (concat "ant -buildfile \""proname"build.xml\" \n"))
  (end-of-buffer)
  (other-window -1))

(defun* gae-java-start-appserver (&optional (port nil))
  "Open shell to start gae appserver"
  (interactive)
  (save-buffer buffer-file-name)
  (unless (and (not (equal nil gae-java-root-path))
               (file-exists-p gae-java-root-path))
    (error "[appengine] Cannot find gae-java-root-path."))
  (if (eq nil port)
      (progn
        (appengine-check-server-hash buffer-file-name)
        (setq port appengine-server-port)))
  ;; get ready buffer
  (setq bufname (concat "*gae-java-appserver-"port"*"))
  (if (not (eq nil (get-buffer bufname)))
      (kill-buffer bufname))
  (setq proname (replace-regexp-in-string "build.xml" "" buffer-file-name))
  (shell bufname)
  ;; start server
  (comint-send-string (current-buffer) (concat "echo '[appengine] AppServer Starting "proname"...' \n"))
  (if (eq system-type 'windows-nt)
      (comint-send-string (current-buffer) (concat "\""gae-java-root-path"/bin/dev_appserver.cmd\" --port="port" \""proname"www\" \n"))
    (comint-send-string (current-buffer) (concat "\""gae-java-root-path"/bin/dev_appserver.sh\" --port="port" \""proname"www\" \n")))
  (end-of-buffer)
  (other-window -1))

(defun gae-java-update-appserver ()
  "Update appserver"
  (interactive)
  (unless (and (not (equal nil gae-java-root-path))
               (file-exists-p gae-java-root-path))
    (error "[appengine] Cannot find gae-java-root-path."))
  (save-some-buffers)
  (setq proname (replace-regexp-in-string "build.xml" "" buffer-file-name))
  (shell "*appengine-temp*")
  (comint-send-string (current-buffer) (concat "echo '[appengine] AppServer Updateing "proname"...' \n"))
  (if (eq system-type 'windows-nt)
      (comint-send-string (current-buffer) (concat "\""gae-java-root-path"/bin/appcfg.cmd\" update \""proname"www\" \n"))
    (comint-send-string (current-buffer) (concat "\""gae-java-root-path"/bin/appcfg.sh\" update \""proname"www\" \n")))
  (end-of-buffer)
  (other-window -1))

;; For project

(defun gae-java-create-project (projectpath projectname)
  "Create new project"
  (unless (and (not (equal nil gae-java-template-directory))
               (file-exists-p gae-java-template-directory))
    (error "[appengine] Cannot find gae template directory!"))
  (copy-directory gae-java-template-directory projectpath)
  (find-file (concat projectpath"/build.xml"))
  (beginning-of-buffer)
  (replace-string "myproject" projectname)
  (replace-string "../.." gae-java-root-path)
  (beginning-of-buffer)
  (save-buffer buffer-file-name)
  (buildxml-mode))

(defun gae-java-new-project ()
  "Create new project"
  (interactive)
  (unless (and (not (equal nil gae-java-root-path))
               (file-exists-p gae-java-root-path))
    (error "[appengine] Cannot find gae-java-root-path."))
  (if (equal nil buffer-file-name)
      (setq tmpprojectpath "~/")
    (setq tmpprojectpath (file-name-directory buffer-file-name)))
  ;; read information from mini buffer
  (let ((projectpath (read-string "[appengine] Project path: "
                                  tmpprojectpath nil tmpprojectpath nil))
        (projectname (read-string "[appengine] Project name (default gae-java-project): "
                                  nil nil "gae-java-project" nil)))
    (setq projectpath (concat projectpath"/"projectname))
    (message "[appengine] Building java project at %s." projectpath)
    (when (and (file-exists-p projectpath) (file-exists-p (concat projectpath"/build.xml")))
      (find-file (concat projectpath"/build.xml"))
      (buildxml-mode)
      (error "[appengine] Project exist!"))
    (if (or (not (file-exists-p projectpath))
            (and (file-exists-p projectpath)
                 (y-or-n-p (format "[appengine] Folder %s exist! Overwrit?" projectpath))))
        (gae-java-create-project projectpath projectname))
    ))

;; define the major mode.

(define-derived-mode buildxml-mode xml-mode "buildxml"
  "buildxml-mode is a major mode for google app engine build.xml file."
  )

(add-to-list 'auto-mode-alist '("\\build.xml\\'" . buildxml-mode))

(provide 'buildxml-mode)

;;; buildxml-mode.el ends here